<?php

/*

CRUD
 * Create
 * Retreive
 * Update
 * Delete

*/

/*** UNCERTAINTY ABOUT Retreive ***/
$objs = Database::retreive($table)->select('*'); //this ->select() method is implied
$objs = Database::select($table, '*'); //same result as above

$obj = Database::retreiveByPK($table, $pk1, $pk2);
$obj = Database::retreiveByCol($table, array(col1 => 1, col2 => 2));

$obj = Database::select()->wherePK($pk1, $pk2);
$obj = Database::wherePK($pk1, $pk2);
$obj = Database::whereCol(array());





$obj = Database::sql("SELECT * FROM table WHERE 1=1");
$obj = Database::sql("INSERT INTO table (pk1, pk2) VALUES (1,2)");
$count = Database::sql("UPDATE table SET pk1 = 2, pk2 = 4 WHERE 1=1");
$count = Database::sql("DELETE FROM table WHERE 1=1");

$objs = Table::select(); //default '*', arguments are a list of the columns to select
$objs = Table::select('pk1', 'pk2');
$objs = Table::select('pk1 as one', 'pk2 as two'); // providing custom names; note that the $schema will need to be modified to account for these aliases?
$objs = Table::select(array(one => 'pk1', two => 'pk2')); 
$objs->where('pk1 = 2');
$objs->join($table, $on, 'inner'); //left, right, outer, inner, left outer, and right outer; if
$objs->limit(0, 2);    //if called after _execute() then array_splice's the returned results
$objs->distinct(true); //default $arg1 = true
$objs->orderby('pk1 DESC', 'pk2 ASC');
$objs->groupby('pk1');

$objs->execute(); //this is implicitly called by any accessor method, such as count(), item(), get(), set(), etc

$obj = Table::selectByPK($pk1Value, $pk2Value); //alternative for select()->where()
$obj = Table::selectByCol(array(col1 => 1, col2 => 2)); //alternative for select()->where()
$obj = Table::sql("SELECT * WHERE 1=1"); //note that FROM [table] is omitted is disallowed
$obj = Table::sql("INSERT (pk1, pk2) VALUES (1,2)"); //note that INTO [table] is omitted is disallowed
$count = Table::sql("UPDATE SET pk1 = 2, pk2 = 4 WHERE 1=1"); //note that table name is omitted and is disallowed
$count = Table::sql("DELETE WHERE 1=1"); //note that table name is omitted and is disallowed

$objs->count();        //number of records in $objs
$obj = $objs->item(n); //returns new $obj with one record; alternative syntax for limit()

$cols = $objs->col; //returns an array of the values of each records "col"
$col = $obj->col;  //returns the single value of the one record's "col"

//The following setters throw an exception if they violate datatype (or user-provided validity and visibility) constraints
$objs->col = array(1,2,3); //number 1 is assigned to first record's 'col', number 2 is assigned to second record's 'col', etc
$objs->col = 2;            //number '2' is assigned to each record's 'col'
$obj->col = 2;

//Possible alternative syntax for getters and setters; setters could return the original object so that we can do chaining; throw exception if property doesn't exist
$obj->get('col');
$obj->set('col', 'value');
$obj->set('col1', 2)
    ->set('col2', 3)
    ->set('col3', 4);

//Attempting to write to read-only properties will result in no action; attempting to write to a non-existant property results in an Exception

//Passing an array or an object to either a constructor or to the ->set() method assigns all of the properties
$data = array(
  id => 1,
  name => "Weston",
  network => "Portland, OR"
);
$obj = new Person($data);
$data['name'] = "Weston Ruter";
$obj->set($data);

$objs = Database::sql("SELECT pk1 as foo, pk2 as bar FROM table WHERE 1=1");
$objs->foo = 1;
$objs->bar = 2;
$objs->save();

//Objects are foreign-key aware
$obj = Table::select()->distinct()->where('pk=1');
$material = Table2::select()->where('pk=2');
$obj->material = 2; //sets the actual value of the foreign key
$obj->material = $material; //sets the value of the foreign key to the value of the primary key in first $material being constrained to; best to do $material->item(0)

//returns the objects of type Table2 (returns multiple if there is a compound PK);
//best to get $obj->item(0)->material, or otherwise it will be the material of all records in $obj
$materials = $obj->material;

//if you want to avoid explicitly JOINing to another table, which references this one:
//given two tables, Person and Poessession, the second of which has a FK to the first:
$person = Person::select()->limit(1);
echo $person->possession->count(); //number of possessions they have

//If you have a table that has FK constraint on a partial PK or a non-PK index, then these are accessed in the same way as above
//Tables: Book, Text, Language

$book = Book::select()->limit(1);
print $book->title->count(); //number of translated titles

//In order to filter the results, we can apply the where() method and it would work since an execute() is done before all accessors
$enTitle = $book->title->where("lang = 'en'");

//What if we then want to get 'Spanish' titles?
$esTitle = $book->title->where("lang = 'es'");
//The previous must create a new instance of Text(), empty the $records, and apply the new where.
//We must make sure that whenever getter is performed, the $book->title is replaced with a new instance.
//Whenever a ->where() is applied to any ORM object, a new instance must be used if Execute() has been previously run; the object should be replaced with a new instance


//We should be able to add new values easily to a one-to-many relationship
$book->title[] = new Text('ar', 'Salaam');


//We must be able to transform the returned columns, from the DB and into the DB; for example, encrypted data


//User::select();


?>